package io.renren.sdapi.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.renren.membermanage.entity.GenerateLog;
import io.renren.sdapi.dto.httprequestparam.ImageRequest;
import io.renren.sdapi.dto.httprequestparam.QueryHistoryDto;
import io.renren.sdapi.dto.httprequestparam.Text2ImageRequestParam;
import io.renren.sdapi.dto.httprequestparam.image2image.BaseParam;
import io.renren.sdapi.dto.httprequestparam.image2image.ExtendedInformation;
import io.renren.sdapi.dto.httprequestparam.image2image.RequestFactory;
import io.renren.sdapi.dto.httprequestparam.image2image.RequestTypeEnum;
import io.renren.sdapi.service.HandleParamService;
import io.renren.sdapi.service.StableDiffusionApiService;
import io.renren.util.ApiResult;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("api")
@Tag(name = "SD 相关Api")
public class StableDiffusionApiController {

    @Resource
    private StableDiffusionApiService stableDiffusionApiService;

    @Resource
    @Qualifier("taskExecutor")
    private ThreadPoolTaskExecutor taskExecutor;

    @Resource
    private HandleParamService handleParamService;

    @SaCheckLogin
    @PostMapping("text2Image")
    @Operation(summary = "text2Image", description = "文本转图片")
    @ApiResponses(value ={
            @ApiResponse(responseCode = "200", description = "请求成功",
                    content = @Content(mediaType = "application/json", schema = @Schema( implementation = ApiResult.class))),
            @ApiResponse(responseCode = "400", description = "请求失败", content = @Content)
    })
    public ApiResult<Map<String, List<String>>> text2Image(@RequestBody Text2ImageRequestParam param) throws Exception{
        //校验及判断入参保存图片的路径
        Map<String, List<String>> map = stableDiffusionApiService.text2Image(param, Long.valueOf(StpUtil.getTokenInfo().getLoginId().toString()));
        return ApiResult.success(map);
    }

    //@SaCheckLogin
    @PostMapping("image2Image")
    public ApiResult<String> image2Image(@RequestBody ImageRequest req) throws Exception {
        if(StrUtil.isBlank(req.getInformation().getUserId())){
            throw new RuntimeException("用户不能为空！");
        }
        BaseParam param = req.getParam();
        String str = stableDiffusionApiService.getLoraStr(req.getLora());
        if (null != str){
            param.setPrompt(stableDiffusionApiService.analyzeWord(param.getPrompt()) + "," + str);
        }else {
            param.setPrompt(stableDiffusionApiService.analyzeWord(param.getPrompt()));
        }
        param.setPrompt(param.getPrompt() + ",masterpiece,High quality");
        ExtendedInformation information = req.getInformation();
        if(StrUtil.isBlank(information.getRequestType())){
            throw new RuntimeException("模式类型不能为空！");
        }
        Object o = null;
        if(information.getRequestType().equals(RequestTypeEnum.TYPE_A.getType())){
            if(0 >= information.getDenoising_strength2()){
                throw new RuntimeException("线稿模式下，请传入对应的重绘幅度！");
            }
            o = handleParamService.getAlwaysonScriptsWithLine(RequestTypeEnum.TYPE_A.getType());
        }
        if(information.getRequestType().equals(RequestTypeEnum.TYPE_B.getType())){
            if(0 >= information.getDenoising_strength3() && StrUtil.isBlank(information.getAlbugineaType())){
                throw new RuntimeException("白膜模式下，请传入对应的参数！");
            }
            o = handleParamService.getAlwaysonScriptsWithAlbuginea(RequestTypeEnum.TYPE_B.getType(), information.getAlbugineaType());
        }
        if(information.getRequestType().equals(RequestTypeEnum.TYPE_C.getType())){
            if(null == information.getDetailingOption()){
                throw new RuntimeException("细化模式下，请传入对应的信息！");
            }
            o = handleParamService.getAlwaysonScriptsWithDetailing(RequestTypeEnum.TYPE_C.getType());
        }
        if(information.getRequestType().equals(RequestTypeEnum.TYPE_D.getType())){
            if(StrUtil.isBlank(information.getImage()) || 0 >= information.getWeight1() || 0 >= information.getWeight3()){
                throw new RuntimeException("灵感融合模式下，请传入对应的图片信息！");
            }
            o = handleParamService.getAlwaysonScriptsWithInspiration(RequestTypeEnum.TYPE_D.getType(), information.getWeight1(), information.getWeight3(), information.getImage(), param.getInit_images()[0]);
        }
        if(information.getRequestType().equals(RequestTypeEnum.TYPE_E.getType())){
            if(StrUtil.isBlank(information.getMask())){
                throw new RuntimeException("局部重绘模式下，请传入对应的图片信息！");
            }
            o = handleParamService.getAlwaysonScriptsWithRedrawing(RequestTypeEnum.TYPE_E.getType(), information.getRedrawingType());
        }
        Class<? extends BaseParam> requestType = RequestTypeEnum.getClassByType(information.getRequestType());
        Map<String, Object> map = BeanUtil.beanToMap(param);
        BaseParam request = RequestFactory.createRequest(requestType, map, information, o);
        taskExecutor.execute(() -> {
            try {
                stableDiffusionApiService.image2Image(request, Long.valueOf(information.getUserId()));
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });
        return ApiResult.build(200, "图片处理进度较慢，这可能需要几分钟时间请耐心等待！");
    }

    @SaCheckLogin
    @GetMapping("image2Image")
    public ApiResult<String> image2Image(){
        stableDiffusionApiService.getLoraSsOutputName("D:/sdapp/stable-diffusion-webui/models/Lora/CR300AF.safetensors");
        return ApiResult.success("");
    }


//    @SaCheckLogin
    @GetMapping("getHistory")
    public ApiResult<Page<GenerateLog>> getHistory(QueryHistoryDto dto){
        Page<GenerateLog> data = stableDiffusionApiService.getHistory(dto);
       return ApiResult.success(data);
    }

    //    @SaCheckLogin
    @GetMapping("getOneHistory")
    public ApiResult<GenerateLog> getOneHistory(Long id){
        GenerateLog data = stableDiffusionApiService.getOneHistory(id);
        return ApiResult.success(data);
    }
}
